package me.zhengjie.pm.taskprogress.service.impl;

import me.zhengjie.hr.employeebase.domain.EmployeeBase;
import me.zhengjie.hr.employeebase.service.dto.EmployeeBaseDto;
import me.zhengjie.hr.employeebase.service.mapper.EmployeeBaseMapper;
import me.zhengjie.pm.projectbase.domain.ProjectBase;
import me.zhengjie.pm.projectbase.service.dto.ProjectBaseDto;
import me.zhengjie.pm.projectbase.service.mapper.ProjectBaseMapper;
import me.zhengjie.pm.taskprogress.domain.TaskProgress;
import me.zhengjie.pm.taskprogress.domain.WorkhoursBase;
import me.zhengjie.pm.taskprogress.domain.WorkhoursDetail;
import me.zhengjie.pm.taskprogress.domain.WorkhoursStatisticsExcel;
import me.zhengjie.utils.ValidationUtil;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.pm.taskprogress.repository.TaskProgressRepository;
import me.zhengjie.pm.taskprogress.service.TaskProgressService;
import me.zhengjie.pm.taskprogress.service.dto.TaskProgressDto;
import me.zhengjie.pm.taskprogress.service.dto.TaskProgressQueryCriteria;
import me.zhengjie.pm.taskprogress.service.mapper.TaskProgressMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;

import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
* @author yuxj
* @date 2020-04-14
*/
@Service
//@CacheConfig(cacheNames = "taskProgress")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class TaskProgressServiceImpl implements TaskProgressService {

    private final TaskProgressRepository taskProgressRepository;

    private final TaskProgressMapper taskProgressMapper;

    @Autowired
    private ProjectBaseMapper projectBaseMapper;

    @Autowired
    private EmployeeBaseMapper employeeBaseMapper;

    public TaskProgressServiceImpl(TaskProgressRepository taskProgressRepository, TaskProgressMapper taskProgressMapper) {
        this.taskProgressRepository = taskProgressRepository;
        this.taskProgressMapper = taskProgressMapper;
    }

    @Override
    //@Cacheable
    public Map<String,Object> queryAll(TaskProgressQueryCriteria criteria, Pageable pageable){
        Page<TaskProgress> page = taskProgressRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(taskProgressMapper::toDto));
    }

    @Override
    //@Cacheable
    public List<TaskProgressDto> queryAll(TaskProgressQueryCriteria criteria){
        return taskProgressMapper.toDto(taskProgressRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    //@Cacheable(key = "#p0")
    public TaskProgressDto findById(Integer id) {
        TaskProgress taskProgress = taskProgressRepository.findById(id).orElseGet(TaskProgress::new);
        ValidationUtil.isNull(taskProgress.getId(),"TaskProgress","id",id);
        return taskProgressMapper.toDto(taskProgress);
    }

    @Override
    //@CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public TaskProgressDto create(TaskProgress resources) {
        return taskProgressMapper.toDto(taskProgressRepository.save(resources));
    }

    @Override
    //@CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void update(TaskProgress resources) {
        TaskProgress taskProgress = taskProgressRepository.findById(resources.getId()).orElseGet(TaskProgress::new);
        ValidationUtil.isNull( taskProgress.getId(),"TaskProgress","id",resources.getId());
        taskProgress.copy(resources);
        taskProgressRepository.save(taskProgress);
    }

    @Override
    //@CacheEvict(allEntries = true)
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            taskProgressRepository.deleteById(id);
        }
    }
    //需要重写一个downloadExcel方法去根据此统计数据的结构去生成excel
    @Override
    public void workhoursDownload(List<TaskProgressDto> all, List<ProjectBaseDto> projectBaseDtos,
                                  List<EmployeeBaseDto> employeeList, HttpServletResponse response) throws IOException {

        WorkhoursStatisticsExcel workhoursStatisticsExcel = new WorkhoursStatisticsExcel();
        workhoursStatisticsExcel.setEmployeeBases(employeeBaseMapper.toEntity(employeeList));
        workhoursStatisticsExcel.setProjectBases(projectBaseMapper.toEntity(projectBaseDtos));

        //map，key=员工ID
        Map<Integer,WorkhoursBase> workMap = new LinkedHashMap<>();

        for (EmployeeBaseDto employeeBaseDto : employeeList){
            WorkhoursBase workhoursBase = new WorkhoursBase();
            workhoursBase.setWorkerId(employeeBaseDto.getId());
            workhoursBase.setWorkerName(employeeBaseDto.getEmpName());
            workhoursBase.setCenterName(employeeBaseDto.getCenterBase().getCenterName());
            workMap.put(employeeBaseDto.getId(),workhoursBase);
        }
        //key为员工ID
        for (TaskProgressDto taskProgress : all) {
            //如果有这名员工，则把该周期内的每条周报信息填入其details中
            //重复数据在插入端进行校验，避免重复插入，这里不做校验
            if (taskProgress.getStaffWorkTask() == null){
                continue;
            }
            int currentId = taskProgress.getStaffWorkTask().getWorkerId();
            if (workMap.containsKey(currentId)){
                WorkhoursBase tBase= workMap.get(currentId);
                //将该员工对应的周报都存入，在实体内部调用逻辑处理
                tBase.addTaskProgressDetails(taskProgress);
                workMap.put(currentId,tBase);
            }
        }
        //为每个员工生成一个数据对象,存入list中
        List<WorkhoursBase> list = new ArrayList<>();
        Iterator<Map.Entry<Integer,WorkhoursBase>> it = workMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<Integer,WorkhoursBase> entry = (Map.Entry<Integer,WorkhoursBase>) it.next();
            WorkhoursBase temp = entry.getValue();
            temp.dataStatistics();
            list.add(temp);
        }

        workhoursStatisticsExcel.setWorkhoursBases(list);
        //先直接代码添加测试数据
        //需要实现这样一个方法FileUtil.downloadExcel(workhoursStatisticsExcel, response);
        //FileUtil.downloadExcel(list, response);
    }

    @Override
    public void download(List<TaskProgressDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TaskProgressDto taskProgress : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("任务id", taskProgress.getTaskId());
            map.put("所属汇总进度表", taskProgress.getCollectId());
            map.put("自我评定的任务完成进度", taskProgress.getProgress());
            map.put("更新时间", taskProgress.getUpdateTime());
            map.put("工作地点", taskProgress.getAddress());
            map.put("本周此项目耗时", taskProgress.getTimeUse());
            map.put("风险描述", taskProgress.getRiskDesc());
            map.put("工作类型", taskProgress.getWorkType());
            map.put("本周时间花费", taskProgress.getWorkhoursDetail());
            map.put("后续工作", taskProgress.getWorkLater());
            map.put("本周期开始时间", taskProgress.getTimeBegin());
            map.put("本周期结束始时间", taskProgress.getTimeEnd());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}